<?php

/**
 * Name: 签到服务层
 * User: Silent
 * Date: 2025-11-07
 * Time: 16:00:00
 */

namespace App\Services\Checkin;

use App\Models\Checkin\SignInRecord;
use App\Repositories\Checkin\SignInRecordRepository;
use App\Repositories\Checkin\DutyLeaderRepository;
use App\Repositories\Checkin\DutySupervisorRepository;
use App\Repositories\Checkin\LeaderReviewRepository;
use App\Repositories\Checkin\SupervisorReviewRepository;
use App\Services\BaseService;
use App\Services\Checkin\NotificationService;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Exception;

class CheckinService extends BaseService
{
    protected $signInRecordRepository;
    protected $dutyLeaderRepository;
    protected $dutySupervisorRepository;
    protected $notificationService;
    protected $leaderReviewRepository;
    protected $supervisorReviewRepository;

    public function __construct(
        SignInRecordRepository $signInRecordRepository,
        DutyLeaderRepository $dutyLeaderRepository,
        DutySupervisorRepository $dutySupervisorRepository,
        NotificationService $notificationService,
        LeaderReviewRepository $leaderReviewRepository,
        SupervisorReviewRepository $supervisorReviewRepository
    ) {
        $this->signInRecordRepository = $signInRecordRepository;
        $this->dutyLeaderRepository = $dutyLeaderRepository;
        $this->dutySupervisorRepository = $dutySupervisorRepository;
        $this->notificationService = $notificationService;
        $this->leaderReviewRepository = $leaderReviewRepository;
        $this->supervisorReviewRepository = $supervisorReviewRepository;
    }

    /**
     * 提交签到
     */
    public function submitSignIn($employee, $signData)
    {
        try {
            DB::beginTransaction();

            // 检查今天是否已经签到
            if ($this->signInRecordRepository->hasSignedToday($employee->id)) {
                throw new Exception('今天已经签到过了，不能重复签到');
            }

            // 创建签到记录
            $signRecord = $this->signInRecordRepository->createSignRecord(
                $employee->toArray(),
                $signData
            );

            // // 如果签到异常，发送通知给当班班长
            // if ($signRecord->status === SignInRecord::STATUS_ABNORMAL) {
            //     $this->notifyDutyLeaders($signRecord);
            // }

            DB::commit();

            return [
                'success' => true,
                'data' => $signRecord,
                'message' => '签到成功'
            ];

        } catch (Exception $e) {
            DB::rollBack();

            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 获取签到日历数据
     */
    public function getSignInCalendar($employee, $year, $month)
    {
        try {
            // 获取员工签到记录
            $signRecords = $this->signInRecordRepository->getEmployeeCalendar(
                $employee->id,
                $year,
                $month
            );

            // 生成日历数据
            $calendar = $this->buildCalendarData($year, $month, $signRecords);

            // 获取用户权限
            $userRole = $this->getUserRole($employee);
            $permissions = $this->getUserPermissions($employee);

            return [
                'success' => true,
                'data' => [
                    'calendar' => $calendar,
                    'user_role' => $userRole,
                    'permissions' => $permissions
                ]
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 获取签到详情
     */
    public function getSignInDetail($employee, $date)
    {
        try {
            $userRole = $this->getUserRole($employee);

            switch ($userRole) {
                case 'employee':
                    return $this->getEmployeeSignDetail($employee, $date);

                case 'leader':
                case 'duty_leader':
                    return $this->getLeaderSignDetail($employee, $date);

                case 'supervisor':
                    return $this->getSupervisorSignDetail($employee, $date);

                default:
                    throw new Exception('无效的用户角色');
            }

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 获取员工签到详情
     */
    private function getEmployeeSignDetail($employee, $date)
    {
        $signRecord = $this->signInRecordRepository->getEmployeeSignRecord(
            $employee->id,
            $date
        );

        if (!$signRecord) {
            throw new Exception('未找到签到记录');
        }

        return [
            'success' => true,
            'data' => [
                'type' => 'employee',
                'date' => $date,
                'employee_name' => $employee->name,
                'team_name' => $employee->team,
                'sign_record' => $signRecord
            ]
        ];
    }

    /**
     * 获取班长签到详情
     */
    private function getLeaderSignDetail($employee, $date)
    {
        // 检查当天是否是值班班长，优先使用值班班组
        $dutyLeader = $this->dutyLeaderRepository->getDutyLeaderByEmployeeAndDate($employee->id, $date);
        $teamName = $dutyLeader ? $dutyLeader->team_name : $employee->team;

        // 获取班组签到记录（包括所有在该班组打卡的成员）
        $signRecords = $this->signInRecordRepository->getTeamSignRecords(
            $teamName,
            $date
        );

        // 按状态分组
        $groupedRecords = $signRecords->groupBy('status');

        // 获取当前班组的班长审核记录
        $leaderReview = $this->leaderReviewRepository->getLeaderReview($teamName, $date);

        // 获取当天的值班领导信息
        $dutySupervisor = $this->dutySupervisorRepository->getDutySupervisorByDate($date);

        return [
            'success' => true,
            'data' => [
                'type' => 'leader',
                'date' => $date,
                'team_name' => $teamName,
                'is_duty_leader' => $dutyLeader ? true : false,
                'duty_leader_info' => $dutyLeader,
                'sign_records' => $signRecords,
                'abnormal_count' => $groupedRecords->get('abnormal', collect())->count(),
                'normal_count' => $groupedRecords->get('normal', collect())->count(),
                'total_count' => $signRecords->count(),
                'review_record' => $leaderReview,
                'duty_supervisor' => $dutySupervisor  // 新增值班领导信息
            ]
        ];
    }

    /**
     * 获取主管签到详情
     */
    private function getSupervisorSignDetail($employee, $date)
    {
        // 获取所有班组的签到记录
        $allSignRecords = $this->signInRecordRepository->getAllTeamsSignRecords($date);

        $teamsData = [];
        foreach ($allSignRecords as $teamName => $records) {
            $groupedRecords = $records->groupBy('status');
            $teamsData[] = [
                'team_name' => $teamName,
                'sign_records' => $records,
                'abnormal_count' => $groupedRecords->get('abnormal', collect())->count(),
                'normal_count' => $groupedRecords->get('normal', collect())->count(),
                'total_count' => $records->count()
            ];
        }

        // 获取当天所有班长的审核记录
        $leaderReviews = $this->leaderReviewRepository->getDailyReviews($date);

        // 获取当天主管的审核记录
        $supervisorReview = $this->supervisorReviewRepository->getSupervisorReview($employee->id, $date);

        return [
            'success' => true,
            'data' => [
                'type' => 'supervisor',
                'date' => $date,
                'teams_data' => $teamsData,
                'review_records' => [
                    'leader_reviews' => $leaderReviews,
                    'supervisor_review' => $supervisorReview
                ]
            ]
        ];
    }

    /**
     * 构建日历数据
     */
    private function buildCalendarData($year, $month, $signRecords)
    {
        $calendar = [];
        $startDate = Carbon::createFromDate($year, $month, 1);
        $endDate = $startDate->copy()->endOfMonth();
        $today = today();

        for ($date = $startDate->copy(); $date->lte($endDate); $date->addDay()) {
            $dateStr = $date->format('Y-m-d');
            $signRecord = $signRecords->get($dateStr);

            $status = 'empty'; // 默认未签到
            if ($signRecord) {
                $status = $signRecord->status;
            }

            $calendar[] = [
                'date' => $dateStr,
                'status' => $status,
                'can_click' => $date->lte($today), // 当前日期及之前可点击
                'is_today' => $date->equalTo($today)
            ];
        }

        return $calendar;
    }

    /**
     * 获取用户角色
     */
    private function getUserRole($employee)
    {
        $position = $employee->position;

        if (in_array($position, ['主管', '部长', '副部长'])) {
            return 'supervisor';
        } elseif (in_array($position, ['班长', '组长'])) {
            // 检查是否为当班班长
            $isDutyLeader = $this->dutyLeaderRepository->getTeamDutyLeader(
                $employee->team,
                today()
            );

            return $isDutyLeader ? 'duty_leader' : 'leader';
        } else {
            // 副班长及其他职位都是普通员工权限
            return 'employee';
        }
    }

    /**
     * 获取用户权限
     */
    private function getUserPermissions($employee)
    {
        $role = $this->getUserRole($employee);

        $permissions = [
            'can_review' => in_array($role, ['leader', 'duty_leader', 'supervisor']),
            'can_set_duty' => $role === 'supervisor',
            'can_view_all_teams' => $role === 'supervisor',
        ];

        return $permissions;
    }

    /**
     * 通知当班班长
     */
    private function notifyDutyLeaders($signRecord)
    {
        try {
            // 获取当天的当班班长
            $dutyLeaders = $this->dutyLeaderRepository->getTodayDutyLeaders();

            foreach ($dutyLeaders as $dutyLeader) {
                // 如果是同一个班组，发送通知
                if ($dutyLeader->team_name === $signRecord->team_name) {
                    $this->notificationService->sendSignInNotification(
                        $dutyLeader->leader,
                        $signRecord
                    );
                }
            }
        } catch (Exception $e) {
            \Log::error('发送签到通知失败', [
                'error' => $e->getMessage(),
                'sign_record_id' => $signRecord->id
            ]);
        }
    }

    /**
     * 获取签到记录列表
     */
    public function getSignInList($employee, $params = [])
    {
        try {
            // 获取查询参数
            $page = $params['page'] ?? 1;
            $limit = $params['limit'] ?? 20;
            $month = $params['month'] ?? null;
            $status = $params['status'] ?? null;

            // 构建查询
            $query = $this->signInRecordRepository->query()
                ->where('employee_id', $employee->id);

            // 月份筛选
            if ($month) {
                // 验证月份格式 YYYY-MM
                if (preg_match('/^\d{4}-\d{2}$/', $month)) {
                    $startDate = Carbon::createFromFormat('Y-m', $month)->startOfMonth();
                    $endDate = Carbon::createFromFormat('Y-m', $month)->endOfMonth();
                    $query->whereBetween('sign_date', [$startDate, $endDate]);
                }
            }

            // 状态筛选
            if ($status && in_array($status, ['normal', 'abnormal'])) {
                $query->where('status', $status);
            }

            // 获取总数
            $total = $query->count();

            // 分页查询
            $offset = ($page - 1) * $limit;
            $signRecords = $query->orderBy('sign_date', 'desc')
                ->orderBy('created_at', 'desc')
                ->offset($offset)
                ->limit($limit)
                ->get();

            // 格式化返回数据
            $formattedRecords = $signRecords->map(function ($record) {
                return [
                    'id' => $record->id,
                    'team_name' => $record->team_name,
                    'sign_date' => $record->sign_date->format('Y-m-d'),
                    'sign_time' => $record->sign_time->format('H:i'),
                    'sign_datetime' => $record->sign_time->format('Y-m-d H:i:s'),
                    'status' => $record->status,
                    'status_text' => $record->status === 'normal' ? '正常' : '异常',
                    'temperature' => $record->temperature,
                    'blood_pressure' => $record->blood_pressure_systolic . '/' . $record->blood_pressure_diastolic,
                    'has_abnormal' => $record->status === 'abnormal',
                    'abnormal_desc' => $record->abnormal_desc, // 异常项描述
                    'remark' => $record->remark,
                    'created_at' => $record->created_at->format('Y-m-d H:i:s')
                ];
            });

            // 计算分页信息
            $totalPages = ceil($total / $limit);
            $hasNextPage = $page < $totalPages;
            $hasPrevPage = $page > 1;

            return [
                'success' => true,
                'data' => [
                    'records' => $formattedRecords,
                    'pagination' => [
                        'current_page' => (int)$page,
                        'per_page' => (int)$limit,
                        'total' => $total,
                        'total_pages' => $totalPages,
                        'has_next_page' => $hasNextPage,
                        'has_prev_page' => $hasPrevPage,
                        'from' => $total > 0 ? $offset + 1 : 0,
                        'to' => min($offset + $limit, $total)
                    ],
                    'filters' => [
                        'month' => $month,
                        'status' => $status
                    ],
                    'employee_info' => [
                        'id' => $employee->id,
                        'name' => $employee->name,
                        'team' => $employee->team,
                        'position' => $employee->position,
                        'company' => $employee->company ?? '',
                        'department' => $employee->department ?? ''
                    ]
                ]
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * 检查指定日期签到状态
     */
    public function checkSignInStatus($employee, $date)
    {
        try {
            // 获取指定日期的签到记录
            $signRecord = $this->signInRecordRepository->getEmployeeSignRecord($employee->id, $date);

            if (!$signRecord) {
                return [
                    'success' => true,
                    'data' => [
                        'has_signed' => false,
                        'date' => $date,
                        'can_sign' => $date <= today()->format('Y-m-d'), // 只能签今天及之前的
                        'employee_info' => [
                            'id' => $employee->id,
                            'name' => $employee->name,
                            'team' => $employee->team,
                            'company' => $employee->company ?? '',
                            'department' => $employee->department ?? ''
                        ]
                    ]
                ];
            }

            // 返回签到状态信息
            return [
                'success' => true,
                'data' => [
                    'has_signed' => true,
                    'date' => $date,
                    'sign_info' => [
                        'id' => $signRecord->id,
                        'sign_date' => $signRecord->sign_date->format('Y-m-d'),
                        'sign_time' => $signRecord->sign_time->format('H:i'),
                        'sign_datetime' => $signRecord->sign_time->format('Y-m-d H:i:s'),
                        'status' => $signRecord->status,
                        'status_text' => $signRecord->status === 'normal' ? '正常' : '异常',
                        'has_abnormal' => $signRecord->status === 'abnormal',
                        'temperature' => $signRecord->temperature,
                        'blood_pressure' => $signRecord->blood_pressure_systolic . '/' . $signRecord->blood_pressure_diastolic,
                        'remark' => $signRecord->remark
                    ],
                    'can_sign' => false, // 已签到，不能再签
                    'employee_info' => [
                        'id' => $employee->id,
                        'name' => $employee->name,
                        'team' => $employee->team
                    ]
                ]
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }
}

